package green.mapstore;

import groovy.util.GroovyTestCase

public class MapStoreTemplateTest extends GroovyTestCase {

    MapStoreTemplate template

    boolean inited
    def added
    def get
    def commited = 0

    def storeMock = [init : { inited = true }, add : {key, value -> added = [key, value] }, get : { get = it }, commit : { commited++ }] as MapStore

    void setUp(){
        template = new MapStoreTemplate(storeMock)
    }

    void testInitAndEmptyExecute() {
      // when - template is created (i.e. store is inited) but not commited
      assert inited
      assertEquals 0, commited

      // then - execute empty operation
      template.execute{assertNotNull it}

      // assert - store has been commited
      assertEquals 1, commited
    }

  void testExecuteGet() {
    // when - we want to get the same value as the key from the store
    def keyAndValue = 'foo'

    // then - execute get() on the store
    def returned = template.execute {it.get(keyAndValue)}

    // assert - store is commited...
    assertEquals 1, commited
    // ...and returned value is the same as the key
    assertEquals keyAndValue, returned
    // ...and as the stored state
    assertEquals keyAndValue, get
  }

  void testStoreAndGetInSingleExecution() {
    // when - we want to add key/value pair to the store
    def key = 'foo'
    def value = 'bar'

    // then - add it and read it in single template execution
    template.execute {it.add(key, value); it.get(key)}

    // assert - that store has been commited only once...
    assertEquals 1, commited
    // ...and added pair values are correct
    assertEquals key, added[0]
    assertEquals value, added[1]
    // ... and we requested the proper key
    assertEquals key, get
  }

    void testStoreAndGetInSeparatedExecutions() {
    // when - we want to add key/value pair to the store
    def key = 'foo'
    def value = 'bar'

    // then - add it..
    template.execute {it.add(key, value)}
    // ...and read it
    template.execute {it.get(key)}

    // assert - that store has been commited twice...
    assertEquals 2, commited
    // ...and added pair values are correct
    assertEquals key, added[0]
    assertEquals value, added[1]
    // ... and we requested the proper key
    assertEquals key, get
  }

}
